using System.Text.Json;
using Microsoft.AspNetCore.Http;

namespace Lzfy_His_Service.Middleware
{
    /// <summary>
    /// 企业微信访问限制中间件
    /// 在生产环境下限制只允许企业微信访问
    /// </summary>
    public class WeChatWorkAccessMiddleware
    {
        private readonly RequestDelegate _next;
        private readonly ILogger<WeChatWorkAccessMiddleware> _logger;
        private readonly IWebHostEnvironment _env;
        private readonly IConfiguration _configuration;

        public WeChatWorkAccessMiddleware(
            RequestDelegate next,
            ILogger<WeChatWorkAccessMiddleware> logger,
            IWebHostEnvironment env,
            IConfiguration configuration)
        {
            _next = next;
            _logger = logger;
            _env = env;
            _configuration = configuration;
        }

        public async Task InvokeAsync(HttpContext context)
        {
            // 检查是否启用企业微信访问限制
            var enableWeChatWorkRestriction = _configuration.GetValue<bool>("WeChatWork:EnableAccessRestriction", false);
            
            // 开发环境或未启用限制时，直接通过
            if (_env.IsDevelopment() || !enableWeChatWorkRestriction)
            {
                await _next(context);
                return;
            }

            // 检查是否为白名单路径（健康检查、Swagger等）
            if (IsWhitelistedPath(context.Request.Path))
            {
                await _next(context);
                return;
            }

            // 检查User-Agent是否为企业微信
            var userAgent = context.Request.Headers["User-Agent"].ToString();
            if (!IsWeChatWorkUserAgent(userAgent))
            {
                _logger.LogWarning("非企业微信访问被拒绝. Path: {Path}, UserAgent: {UserAgent}, IP: {IP}",
                    context.Request.Path,
                    userAgent,
                    context.Connection.RemoteIpAddress);

                await HandleAccessDenied(context);
                return;
            }

            // 记录企业微信访问日志
            _logger.LogInformation("企业微信访问. Path: {Path}, UserAgent: {UserAgent}, IP: {IP}",
                context.Request.Path,
                userAgent,
                context.Connection.RemoteIpAddress);

            await _next(context);
        }

        /// <summary>
        /// 检查是否为企业微信User-Agent
        /// </summary>
        private static bool IsWeChatWorkUserAgent(string userAgent)
        {
            if (string.IsNullOrEmpty(userAgent))
                return false;

            var lowerUserAgent = userAgent.ToLowerInvariant();
            
            // 企业微信的User-Agent特征
            // 1. 包含 wxwork 标识
            // 2. 包含 micromessenger 但同时包含 wxwork
            return lowerUserAgent.Contains("wxwork") || 
                   (lowerUserAgent.Contains("micromessenger") && lowerUserAgent.Contains("wxwork"));
        }

        /// <summary>
        /// 检查是否为白名单路径
        /// </summary>
        private static bool IsWhitelistedPath(PathString path)
        {
            var pathValue = path.Value?.ToLowerInvariant() ?? string.Empty;
            
            // 白名单路径：健康检查、Swagger、静态文件等
            var whitelistedPaths = new[]
            {
                "/health",
                "/swagger",
                "/api/health",
                "/favicon.ico",
                "/robots.txt",
                "/sitemap.xml"
            };

            return whitelistedPaths.Any(whitePath => pathValue.StartsWith(whitePath));
        }

        /// <summary>
        /// 处理访问被拒绝的情况
        /// </summary>
        private static async Task HandleAccessDenied(HttpContext context)
        {
            context.Response.StatusCode = 403;
            context.Response.ContentType = "application/json; charset=utf-8";

            var response = new
            {
                success = false,
                message = "访问被拒绝：此应用仅允许在企业微信中访问",
                code = "ACCESS_DENIED",
                timestamp = DateTime.UtcNow,
                details = new
                {
                    reason = "WECHAT_WORK_REQUIRED",
                    description = "This application can only be accessed through WeChat Work",
                    userAgent = context.Request.Headers["User-Agent"].ToString(),
                    path = context.Request.Path.Value
                }
            };

            var jsonResponse = JsonSerializer.Serialize(response, new JsonSerializerOptions
            {
                PropertyNamingPolicy = JsonNamingPolicy.CamelCase,
                WriteIndented = true
            });

            await context.Response.WriteAsync(jsonResponse);
        }
    }

    /// <summary>
    /// 企业微信访问限制中间件扩展方法
    /// </summary>
    public static class WeChatWorkAccessMiddlewareExtensions
    {
        /// <summary>
        /// 添加企业微信访问限制中间件
        /// </summary>
        public static IApplicationBuilder UseWeChatWorkAccessRestriction(this IApplicationBuilder builder)
        {
            return builder.UseMiddleware<WeChatWorkAccessMiddleware>();
        }
    }
}